Compute distance to roads

This notebook computes the distance to each of the nearest road types in a 'roads' vector map from a vector map of 'points' (sample locations).

This notebook uses GRASS GIS (7.0.4), and must be run inside of a GRASS environment (start the jupyter notebook server from the GRASS command line).

Required packages

Variable declarations

points – vector map with points to measure distance from (sample locations)
roads – vector map with roads data
road_type_field – field name containing the road classification type (i.e. residential, secondary, etc.)
distance_table_filename – path to export the distances table as a csv file


In [ ]:
points = 'sample_points_field'

In [ ]:
roads = 'highway'

In [ ]:
road_type_field = 'Type'

In [ ]:
distance_table_filename = ""

Import statements


In [ ]:
import pandas
import numpy as np
import pyprind

GRASS import statements


In [ ]:
import grass.script as gscript

from grass.pygrass.vector import VectorTopo
from grass.pygrass.vector.table import DBlinks

Function declarations

connect to an attribute table


In [ ]:
def connectToAttributeTable(map):
    vector = VectorTopo(map)
    vector.open(mode='r')
    dblinks = DBlinks(vector.c_mapinfo)
    link = dblinks[0]
    return link.table()

finds the nearest element in a vector map (to) for elements in another vector map (from)
calls the GRASS v.distance command


In [ ]:
def computeDistance(from_map, to_map):

    upload = 'dist'
    result = gscript.read_command('v.distance',
                         from_=from_map,
                         to=to_map,
                         upload=upload,
                         separator='comma',
                         flags='p')
    return result.split('\n')

selects vector features from an existing vector map and creates a new vector map containing only the selected features
calls the GRASS v.extract command


In [ ]:
def extractFeatures(input_, type_, output):

    where = "{0} = '{1}'".format(road_type_field, type_)
    gscript.read_command('v.extract',
                         input_=input_,
                         where=where,
                         output=output,
                         overwrite=True)

Get unique 'roads' types


In [ ]:
roads_table = connectToAttributeTable(map=roads)
roads_table.filters.select(road_type_field)
cursor = roads_table.execute()
result = np.array(cursor.fetchall())
cursor.close()
road_types = np.unique(result)

In [ ]:
print(road_types)

Get 'points' attribute table


In [ ]:
point_table = connectToAttributeTable(map=points)
point_table.filters.select()
columns = point_table.columns.names()
cursor = point_table.execute()
result = np.array(cursor.fetchall())
cursor.close()
point_data = pandas.DataFrame(result, columns=columns).set_index('cat')

Loop through 'roads' types and compute the distances from all 'points'


In [ ]:
distances = pandas.DataFrame(columns=road_types, index=point_data.index)

In [ ]:
progress_bar = pyprind.ProgBar(road_types.size, bar_char='█', title='Progress', monitor=True, stream=1, width=50)

for type_ in road_types:
    
    # update progress bar
    progress_bar.update(item_id=type_)
    
    # extract road data based on type query
    extractFeatures(input_=roads, type_=type_, output='roads_tmp')
    
    # compute distance from points to road type
    results = computeDistance(points, 'roads_tmp')
    
    # save results to data frame
    distances[type_] = [ d.split(',')[1] for d in results[1:len(results)-1] ]

# match index with SiteID
distances['SiteID'] = point_data['ID']
distances.set_index('SiteID', inplace=True)

Export distances table to a csv file


In [ ]:
distances.to_csv(distance_table_filename, header=False)